package chpt_06_02_state;

/**
 * @author Ping
 * @date 2023/5/11 10:33
 **/
public class StateDemo {
    public static void main(String args[]) {
        NewRoom newRoom = new NewRoom() ;
        newRoom.book() ;
        newRoom.cancle();
        newRoom.checkOut();
        newRoom.checkIn();



    }
}

class Room {
    static final String BOOKED_STATE = "booked" ;
    static final String AVAILABLE_STATE = "available" ;
    static final String OCCUPIED_STATE = "occupied" ;

    /**
     * room properties
     */
    String roomState ;

    public void book() {
        if (this.roomState == AVAILABLE_STATE) {
            System.out.println("可以接受预订")  ;
            this.roomState = BOOKED_STATE ;
        } else if (this.roomState == BOOKED_STATE) {
            System.out.println("很抱歉！该房间已被预订！");
        } else if (this.roomState == OCCUPIED_STATE) {
            System.out.println("很抱歉！该房间已被入住！");
        }

    }
    public void checkIn() {
        if (this.roomState == OCCUPIED_STATE) {
            System.out.println("很抱歉！该房间已被入住！");
        } else if (this.roomState == AVAILABLE_STATE) {
            System.out.println("欢迎入住！")  ;
            this.roomState = OCCUPIED_STATE ;
        } else if (this.roomState == BOOKED_STATE) {
            System.out.println("欢迎入住！")  ;
            this.roomState = OCCUPIED_STATE ;
        }

    }
    public void checkOut() {

    }
    public void cancle() {

    }


}
/**
 * 使用状态模式进行优化
 */


class NewRoom {
    private RoomState state = new AvailableState(this);

    public void setState(RoomState newState) {
        this.state = newState ;
        this.state.setRoom(this);
    }

    public void book() {
        this.state.book() ;
    }
    public void checkIn() {
        this.state.checkIn();
    }
    public void cancle() {
        this.state.cancle() ;
    }
    public void checkOut() {
        this.state.checkOut() ;
    }



}

interface  RoomState {
    public void book() ;
    public void checkIn() ;
    public void cancle() ;
    public void checkOut() ;
    public void setRoom(NewRoom room) ;
}

abstract  class AbstractRoomState implements RoomState {
    protected NewRoom room ;

    public AbstractRoomState(NewRoom room) {
        this.room = room;
    }
}
/**
 * Concrete States:
 *
 */
class AvailableState extends AbstractRoomState {

    public AvailableState(NewRoom room) {
        super(room);
    }

    @Override
    public void book() {
        System.out.println("[INFO] Welcome book.") ;
        /**
         * state transition
         */
        this.room.setState(new BookedState(this.room));
        System.out.println("[INFO] the room was BOOKED.") ;
    }

    @Override
    public void checkIn() {
        System.out.println("[INFO] Welcome check in.") ;
        /**
         * state transition
         */
        this.room.setState(new OccupiedState(this.room));
        System.out.println("[INFO] the room was OCCUPIED.") ;
    }

    @Override
    public void cancle() {
        System.out.println("[WARNING] the room can not canceled, since it was" +
                "  not checked-in or booked !") ;
    }

    @Override
    public void checkOut() {
        System.out.println("[WARNING] the room can not checkout, since it was" +
                "  not checked-in !") ;
    }

    @Override
    public void setRoom(NewRoom room) {
        this.room = room ;
    }
}

class BookedState extends AbstractRoomState {

    public BookedState(NewRoom room) {
        super(room);
    }

    @Override
    public void book() {
        System.out.println("[WARNING] the room can not booked, since it was" +
                "  already booked !") ;
    }

    @Override
    public void checkIn() {
        System.out.println("[INFO] Welcome check in.") ;
        /**
         * state transition
         */
        this.room.setState(new OccupiedState(this.room));
        System.out.println("[INFO] the room was OCCUPIED.") ;
    }

    @Override
    public void cancle() {
        /**
         * state transition
         */
        this.room.setState(new AvailableState(this.room));
        System.out.println("[INFO] the room was canceled.") ;
    }

    @Override
    public void checkOut() {
        System.out.println("[WARNING] the room can not be checkout, since it was" +
                "  not checked in !") ;
    }

    @Override
    public void setRoom(NewRoom room) {
        this.room = room ;
    }
}

class OccupiedState extends AbstractRoomState {
    public OccupiedState(NewRoom room) {
        super(room);
    }

    @Override
    public void book() {
        System.out.println("[WARNING] the room can not booked, since it was" +
                "  not available!") ;
    }

    @Override
    public void checkIn() {
        System.out.println("[WARNING] the room can not be checkin, " +
                "since it was already occupied!") ;
    }

    @Override
    public void cancle() {
        System.out.println("[WARNING] the room can not be canceled, " +
                "since it was already occupied!") ;
    }

    @Override
    public void checkOut() {
        System.out.println("[INFO] Best wishes.") ;
        /**
         * state transition
         */
        this.room.setState(new AvailableState(this.room));
        System.out.println("[INFO] the room was AVAILABLE") ;

    }

    @Override
    public void setRoom(NewRoom room) {
        this.room = room;
    }
}








